<?php


class MySQL
{
	public static $url = 'mysql://username:password@hostname/database';

	public static $useExeception = TRUE;  // прекрашать работу после ошибок
	public static $haltOnError   = FALSE;  // прекрашать работу после ошибок
	public static $showError     = TRUE;   // выводить ошибки
	public static $showSQL       = FALSE;  // показывать запросы
	public static $encoding      = 'UTF8';

	private static $_self;
	
	private $db;
	private $hostname;
	private $username;
	private $password;
	private $database;
	
	private function __construct()
	{
		$this->prepare();
		$this->connect();
	}

	public static function getInstance()
	{
		if(is_null(self::$_self))
			self::$_self = new MySQL();
		
		return self::$_self;
	}
	
    public function query($sql)
	{
		if (empty($sql))
		{
			$this->error('Query was empty!', false);
			return false;
		}
		
		$result = mysql_query($sql, $this->db);

		if (self::$showSQL) 
			echo "<pre><b>SQL:</b> $sql\nID: {$this->db}</pre>";

		if (mysql_error($this->db))
			$this->error('SQL error: ' . mysql_error($this->db) . ' (errno: ' . mysql_errno($this->db) . ")\nSQL Query:\n$sql\n", true);
		
		return $result;
	}
	
	public function begin()
	{
		$this->query("BEGIN WORK");
	}
	
	public function commit()
	{
		$this->query("COMMIT");
	}
	
	public function rollback()
	{
		$this->query("ROLLBACK");
	}
	
	public function fetch_row($res)
	{
		$result = mysql_fetch_row($res);
		if (mysql_error($this->db))
			$this->error(mysql_error($this->db), false);

		return $result;
	}
	
	public function fetch_assoc($res)
	{
		$result = mysql_fetch_assoc($res);
		if (mysql_error($this->db))
			$this->error(mysql_error($this->db), false);

		return $result;
	}
	
	public function fetch_object($res)
	{
		$result = mysql_fetch_object($res);
		if (mysql_error($this->db))
			$this->error(mysql_error($this->db), false);
		
		return $result;
	}
	
	public function free_result($res)
	{
		if (is_resource($res)) 
			mysql_free_result($res);
	}
	
	public function num_rows($res)
	{
		$result = mysql_num_rows($res);
		if (mysql_error($this->db))
			$this->error(mysql_error($this->db), false);
		
		return $result;
	}
	
	public function affected_rows()
	{
		$result = mysql_affected_rows();
		if (mysql_error($this->db))
			$this->error(mysql_error($this->db), false);
		
		return $result;
	}

	public function insert_id()
	{
		$result = mysql_insert_id();
		if (mysql_error($this->db))
			$this->error(mysql_error($this->db), false);
		
		return $result;
	}

	public function escape($str)
	{
		if (is_string($str))
		{
			// если magic_quotes_gpc включена - используем stripslashes
			if (get_magic_quotes_gpc()) {
				$str = stripslashes($str);
			}			
			// $str = str_replace('\'', "'", $str);
			$str = mysql_real_escape_string($str, $this->db);
			// $str = str_replace("\\'", "'", $str);
			// $str = str_replace("\\\"", '"', $str);
			$str = "'".$str."'";
		}
		elseif (is_bool($str))
		{
			$str = ($str === FALSE) ? 0 : 1;
		}
		elseif (is_null($str))
		{
			$str = 'NULL';
		}
		return $str;
	}

	private function error ($error, $critical = true)
	{
		$this->bLastOpResult = false;
		
		if (self::$haltOnError || $critical)
		{
		if(self::$useExeception)
			throw new Exception($error);
		else
				trigger_error($error, E_USER_ERROR);
		}
		else
			trigger_error($error, E_USER_WARNING);
	}
	
	private function connect()
	{
		$this->db = mysql_connect($this->hostname, $this->username, $this->password);
		
		if (mysql_error($this->db))
			$this->error(mysql_error($this->db), true);
			
		if (! empty(self::$encoding))
			$this->query('SET NAMES '.self::$encoding, $this->db);
			// $this->query('/*!40101 SET NAMES "' . self::$encoding . '" */');
			
		mysql_select_db($this->database, $this->db);
	}
	
	private function prepare()
	{
		// parse_url не понимает URL'ы без указания схемы.
		if (! preg_match('|[a-z0-9]+://|i', self::$url))
			$input = 'mysql://' . self::$url;
		
		$params = parse_url(self::$url);
		// print_r($params);
		
		$this->username = $this->testParam($params, 'user', 'missing username');
		$this->password = $this->testParam($params, 'pass', 'missing password');
		$this->hostname = $this->testParam($params, 'host', 'missing hostname');
		$this->database = $this->testParam($params, 'path', 'missing database');
		$this->database = substr($this->database, 1);
	}
	
	private function testParam($params, $name, $error)
	{
		if (empty($params[$name]))
			$this->error($error, 1);
		
		return $params[$name];
	}
}

